package com.feishi.core.util.common;

import com.feishi.core.util.common.bean.CallBack;
import com.feishi.core.util.common.bean.CallBackForTwo;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by caixq on 4/7 007.
 */
public class FileUtil {
    public static boolean exists(String filePath) {
        File file=new File(filePath);
        return file.exists();
    }

    public static void ergodic(File file,String pattern, CallBack<File> fileCallBack) {
        if (file.isDirectory()) {//文件夹
            //文件夹我们就递归
            File[] files = file.listFiles();
            for (File f1 : files) {
                ergodic(f1,pattern,fileCallBack) ;
            }
        } else {//标准文件
            //标准文件我们就判断是否是目标文件
            if (file.getName().toLowerCase().matches(pattern)) {
                //如果是目标文件我们就放入我们的集合中。
                fileCallBack.execute(file);
            }else {
                System.out.println(file.getName());
            }
        }
    }

    /**
     * 遍历文件夹
     * */
    public void walkFileTree(String filePath,FileVisitor<Path> visitor) throws IOException {
        Files.walkFileTree(Paths.get(filePath), visitor);
    }

    public void walkFileTree(String filePath,CallBackForTwo<Path,BasicFileAttributes> callBack) throws IOException {
        Files.walkFileTree(Paths.get(filePath), new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                callBack.execute(file,attrs);
                return FileVisitResult.CONTINUE;
            }
        });
    }

    public static boolean delete(String filePath) {
        File file=new File(filePath);
        if(file.exists()){
            file.delete();
            return true;
        }
        return false;
    }
    public static OutputStream getOutputStream(String path) throws FileNotFoundException {
        return new FileOutputStream(path);
    }

    public static InputStream getInputStream(String path) throws FileNotFoundException {
        return new FileInputStream(path);
    }
    public static boolean existsDir(String filePath) {
        // TODO Auto-generated method stub
        File file=new File(filePath);
        return file.exists()&&file.isDirectory();
    }

    public static boolean existsFile(String filePath) {
        // TODO Auto-generated method stub
        File file=new File(filePath);
        return file.exists()&&file.isFile();
    }
    public static File createDir(String filePath) {
        // TODO Auto-generated method stub
        File file=new File(filePath);
        if(!file.exists()){
            file.mkdirs();
        }
        return file;
    }

    public static List<File> searchFile(String basePath, String pattern) {
        return searchFile(new File(basePath),".*("+pattern+").*");
    }
    public static List<File> searchFile(File file, String pattern) {
        List<File> result=new ArrayList<>();
        if (file.isDirectory()) {//文件夹
            //文件夹我们就递归
            File[] files = file.listFiles();
            for (File f1 : files) {
                result.addAll(searchFile(f1,pattern)) ;
            }
        } else {//标准文件
            //标准文件我们就判断是否是目标文件
            if (file.getName().matches(pattern)) {
                //如果是目标文件我们就放入我们的集合中。
                result.add(file);
            }
        }
        return result;
    }
    public static void renameFile(String basePath,String oldCharSet,String newCharSet){
        File file=new File(basePath);
        renameFile(file,oldCharSet,newCharSet);

    }
    public static void renameFile(File file,String oldCharSet,String newCharSet){
        if(file.isDirectory()){
            if(oldCharSet.contains(".")){
                String[] chars = oldCharSet.split("\\.");
                boolean result=true;
                File f=file;
                for (int i = 0; i < chars.length; i++) {
                    if(!f.getName().equals(chars[chars.length-1-i])){
                        result=false;
                        break;
                    }
                    f=f.getParentFile();
                }
                if(result==true){
                    String[] s = newCharSet.split(".");
                    f=new File(f.getPath()+"/"+newCharSet.replaceAll("\\.","/"));
                    moveDirectory(file.getPath(),f.getPath());
                    file=new File(f.getPath());
                }
            }
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) renameFile(files[i], oldCharSet, newCharSet);
        }else{
            if(oldCharSet.indexOf(".")==1){
                if(file.getName().contains(oldCharSet)){
                    File f =new File(file.getParent()+File.pathSeparator+file.getName().replace(oldCharSet,newCharSet));
                    file.renameTo(f);
                }
            }
        }
    }
    /**
     * 移动目录
     * @param srcDirName     源目录完整路径
     * @param destDirName    目的目录完整路径
     * @return 目录移动成功返回true，否则返回false
     */
    public static boolean moveDirectory(String srcDirName, String destDirName) {

        File srcDir = new File(srcDirName);
        if(!srcDir.exists() || !srcDir.isDirectory())
            return false;

        File destDir = new File(destDirName);
        if(!destDir.exists())
            destDir.mkdirs();

        /**
         * 如果是文件则移动，否则递归移动文件夹。删除最终的空源文件夹
         * 注意移动文件夹时保持文件夹的树状结构
         */
        File[] sourceFiles = srcDir.listFiles();
        for (File sourceFile : sourceFiles) {
            if (sourceFile.isFile())
                moveFile(sourceFile.getAbsolutePath(), destDir.getAbsolutePath());
            else if (sourceFile.isDirectory())
                moveDirectory(sourceFile.getAbsolutePath(),
                        destDir.getAbsolutePath() + File.separator + sourceFile.getName());
            else
                ;
        }
        return srcDir.delete();
    }
    /**
     * 移动文件
     * @param srcFileName    源文件完整路径
     * @param destDirName    目的目录完整路径
     * @return 文件移动成功返回true，否则返回false
     */
    public static boolean moveFile(String srcFileName, String destDirName) {

        File srcFile = new File(srcFileName);
        if(!srcFile.exists() || !srcFile.isFile())
            return false;

        File destDir = new File(destDirName);
        if (!destDir.exists())
            destDir.mkdirs();

        return srcFile.renameTo(new File(destDirName + File.separator + srcFile.getName()));
    }

    /**
     * 复制文件
     * @param file    源文件(夹)
     * @param toFile    目的文件(夹)
     */
    public static void copyFiles(File file, File toFile) throws IOException {

        byte[] b = new byte[1024];
        int a;


        FileInputStream fis;
        FileOutputStream fos;
        if (file.isDirectory()) {
            String filepath = file.getAbsolutePath();
            filepath=filepath.replaceAll("\\\\", "/");
            String toFilepath = toFile.getAbsolutePath();
            toFilepath=toFilepath.replaceAll("\\\\", "/");
            int lastIndexOf = filepath.lastIndexOf("/");
            toFilepath = toFilepath + filepath.substring(lastIndexOf ,filepath.length());
            File copy=new File(toFilepath);
            //复制文件夹
            if (!copy.exists()) {
                copy.mkdir();
            }
            //遍历文件夹
            for (File f : file.listFiles()) {
                copyFiles(f, copy);
            }
        } else {
            if (toFile.isDirectory()) {
                String filepath = file.getAbsolutePath();
                filepath=filepath.replaceAll("\\\\", "/");
                String toFilepath = toFile.getAbsolutePath();
                toFilepath=toFilepath.replaceAll("\\\\", "/");
                int lastIndexOf = filepath.lastIndexOf("/");
                toFilepath = toFilepath + filepath.substring(lastIndexOf ,filepath.length());

                //写文件
                File newFile = new File(toFilepath);
                fis = new FileInputStream(file);
                fos = new FileOutputStream(newFile);
                while ((a = fis.read(b)) != -1) {
                    fos.write(b, 0, a);
                }
            } else {
                //写文件
                fis = new FileInputStream(file);
                fos = new FileOutputStream(toFile);
                while ((a = fis.read(b)) != -1) {
                    fos.write(b, 0, a);
                }
                fos.flush();
                fos.close();
                fis.close();
            }

        }
    }
    public static void main(String[] args) {
        String basePath="E:\\launch-iot-parent";
        renameFile(basePath,"cn.com.launch.core","cn.launchai.core");
        clearDir(new File(basePath),"cn.com.launch");

    }

    private static void clearDir(File file, String target) {
        if(file.isDirectory()){
            if(target.contains(".")){
                String[] chars = target.split("\\.");
                boolean result=true;
                File f=file;
                for (int i = 0; i < chars.length; i++) {
                    if(!f.getName().equals(chars[chars.length-1-i])){
                        result=false;
                        break;
                    }
                    f=f.getParentFile();
                }
                if(result==true){
                    while (file.listFiles().length==0){
                        file.delete();
                        file=file.getParentFile();
                    }
                }else{
                    File[] files = file.listFiles();
                    for (File file1 : files) {
                        clearDir(file1, target);
                    }
                }
            }else if(file.getName().equals(target)){
                while (file.listFiles().length==0){
                    file.delete();
                    file=file.getParentFile();
                }
            }else{
                File[] files = file.listFiles();
                for (File file1 : files) {
                    clearDir(file1, target);
                }
            }
        }else{
            return;
        }
    }

    public static void writeStreamToFile(InputStream inputStream, File file) {
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        byte[] b = new byte[1024];
        int a;
        try {
            FileOutputStream fos = new FileOutputStream(file);
            while ((a = inputStream.read(b)) != -1) {
                fos.write(b, 0, a);
            }

            fos.flush();
            fos.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getTempDir() {
        return System.getProperty("java.io.tmpdir");
    }


}
